package com.ecarx.camera.utils;

import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;

import androidx.annotation.NonNull;

/**
 * 节流（间隔时间内频繁操作的话，只取第一次和最近一次的操作）工具类
 *
 * @author : shuliang.zhang
 * @date : 2023/06/12
 */
public class ThrottleUtils {

    private static final String TAG = "ThrottleUtils";

    /**
     * 默认间隔时间
     */
    private static final long THROTTLE_DEFAULT_MS = 500;

    private static final int MSG_FOR_WORKER = 1;

    private long mLastTime;
    private Runnable mWorker;

    /**
     * 节流的间隔时间
     */
    private final long mThrottleMs;

    private final Handler mHandler;

    public ThrottleUtils() {
        this(THROTTLE_DEFAULT_MS);
    }

    public ThrottleUtils(long throttleMs) {
        if (throttleMs <= 0) {
            throttleMs = THROTTLE_DEFAULT_MS;
        }
        this.mThrottleMs = throttleMs;
        this.mHandler = AppExecutors.get().createAsyncHandler(new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {
                switch (msg.what) {
                    case MSG_FOR_WORKER:
                        LogUtils.d(TAG, "handle msg for worker");
                        doWork();
                        break;
                    default:
                        break;
                }
                return true;
            }
        });
    }

    /**
     * 执行操作
     */
    private void doWork() {
        if (mWorker != null) {
            mLastTime = SystemClock.elapsedRealtime();
            LogUtils.d(TAG, "doWork, recordHandleTime time:" + mLastTime);
            mHandler.post(mWorker);
        } else {
            LogUtils.w(TAG, "doWork, but worker is null");
        }
    }

    /**
     * 执行相关操作
     * @param runnable
     */
    public void handle(Runnable runnable) {
        if (runnable == null) {
            return;
        }
        mWorker = runnable;
        long now = SystemClock.elapsedRealtime();
        if (Math.abs(now - mLastTime) < mThrottleMs) {
            if (!mHandler.hasMessages(MSG_FOR_WORKER)) {
                LogUtils.d(TAG, "handle, no pending msg, sendDelay, nowTime:" + now + ", lastTime:" + mLastTime);
                mHandler.sendEmptyMessageDelayed(MSG_FOR_WORKER, mThrottleMs);
            } else {
                LogUtils.d(TAG, "handle, but has pending msg, nowTime:" + now + ", lastTime:" + mLastTime);
            }
            return;
        }
        mHandler.removeMessages(MSG_FOR_WORKER);
        LogUtils.d(TAG, "handle directly, nowTime:" + now + ", lastTime:" + mLastTime);
        mHandler.sendEmptyMessage(MSG_FOR_WORKER);
    }

}
